/*
 * DictManager.cpp
 *
 *  Created on: Jun 9, 2009
 *      Author: walter
 */

#include "DictManager.h"

QString QueryResult::getFinalArticle()
{
	//QString dict_type = DB.getTableValue(0,"dict_type");
	//QString full_name = DB.getTableValue(0,"full_name");
	mFinalArticle.clear();
	QString dictTitle = QString("<FONT COLOR='BLUE'>&lt;---%1---&gt;</FONT>").arg(mDictName);
	mFinalArticle.append(dictTitle);
	//if (mDictType == "xdxf")
	//	mFinalArticle.append("<BR>");

	if (mDictType == "xdxf")
	{
		mFinalArticle.append("<BR>");
		mFinalArticle.append(mArticle);
	}
	else if (mDictType == "txt")
	{
		mFinalArticle.append(QString("<BR><FONT COLOR='%1' SIZE=4><B>").arg("#330033"));
		mFinalArticle.append(QString("%1</B></FONT><BR>").arg(mKey));
		mFinalArticle.append(mArticle);
	}

	mFinalArticle.append("<BR>");

	return mFinalArticle;
}

DictManager::DictManager():
	xdxf_color_key("#330033"),
	xdxf_color_co("#0066ff"),
	xdxf_color_ex("#660099"),
	xdxf_color_kref("#009966"),
	xdxf_color_dtrn("#0000cc"),
	xdxf_color_tense("#3399cc")
{
	loadDicts();
	readSettings();
}

DictManager::~DictManager()
{
	writeSettings();
}

void DictManager::readSettings()
{
	QSettings settings("./configure/ReciteGREWords.conf" , QSettings::IniFormat );
	QVariant val;
	settings.beginGroup( "XDXF" );
	val = settings.value("xdxf_color_key");
	if(val.isValid()) xdxf_color_key = val.toString();

	val = settings.value("xdxf_color_co");
	if(val.isValid()) xdxf_color_co = val.toString();

	val = settings.value("xdxf_color_ex");
	if(val.isValid()) xdxf_color_ex = val.toString();

	val = settings.value("xdxf_color_kref");
	if(val.isValid()) xdxf_color_kref = val.toString();

	val = settings.value("xdxf_color_dtrn");
	if(val.isValid()) xdxf_color_dtrn = val.toString();

	val = settings.value("xdxf_color_tense");
	if(val.isValid()) xdxf_color_tense = val.toString();

	settings.endGroup();

	settings.beginGroup( "Global" );
	mQueryDicts.clear();
	val = settings.value("QueryDicts");
	if(val.isValid())
	{
		//cout<<"DictManager::readSettings-->QueryDicts = "<<val.toString().toUtf8().data()<<endl;
		QStringList queryDicts = val.toString().split("|", QString::SkipEmptyParts);
		for(int i=0; i<queryDicts.size(); i++)
		{
			map<QString, QString>::iterator dict_it = mDictMap.find(queryDicts[i]);
			if (dict_it != mDictMap.end())
				mQueryDicts.push_back(queryDicts[i]);
		}
	}

	mIgnorePhraseDicts.clear();
	val = settings.value("IgnorePhraseDicts");
	if(val.isValid())
	{
		//cout<<"DictManager::readSettings-->QueryDicts = "<<val.toString().toUtf8().data()<<endl;
		QStringList ignorePhraseDicts = val.toString().split("|", QString::SkipEmptyParts);
		for(int i=0; i<ignorePhraseDicts.size(); i++)
		{
			map<QString, QString>::iterator dict_it = mDictMap.find(ignorePhraseDicts[i]);
			if (dict_it != mDictMap.end())
				mIgnorePhraseDicts.push_back(ignorePhraseDicts[i]);
		}
	}
	settings.endGroup();
	//for (int i=0; i<mQueryDicts.size(); i++)
	//	cout<<mQueryDicts[i].toUtf8().data()<<endl;
}

void DictManager::writeSettings()
{
	QSettings settings("./configure/ReciteGREWords.conf" , QSettings::IniFormat );
	settings.beginGroup( "XDXF" );
	settings.setValue("xdxf_color_key", xdxf_color_key);
	settings.setValue("xdxf_color_co", xdxf_color_co);
	settings.setValue("xdxf_color_ex", xdxf_color_ex);
	settings.setValue("xdxf_color_kref", xdxf_color_kref);
	settings.setValue("xdxf_color_dtrn", xdxf_color_dtrn);
	settings.setValue("xdxf_color_tense", xdxf_color_tense);
	settings.endGroup();

	settings.beginGroup( "Global" );
	QStringList queryDicts;
	for(int i=0; i<mQueryDicts.size(); i++)
		queryDicts<<mQueryDicts[i];
	QString queryDictsString = queryDicts.join("|");
	settings.setValue("QueryDicts", queryDictsString);

	QStringList ignorePhraseDicts;
	for(int i=0; i<mIgnorePhraseDicts.size(); i++)
		ignorePhraseDicts<<mIgnorePhraseDicts[i];
	QString ignorePhraseDictsString = ignorePhraseDicts.join("|");
	settings.setValue("IgnorePhraseDicts", ignorePhraseDictsString);

	settings.endGroup();
}

void DictManager::loadDicts()
{
	cout<<"DictManager::loadDicts"<<endl;
	mDictDBs.clear();
	mDicts.clear();
	mDictMap.clear();

	QDir dir = QDir::current();
	dir.cd("data");
	dir.cd("common");

	QStringList filter;
	filter<<"*.db";
	QStringList files = dir.entryList(filter);
	for (int i=0; i<files.size(); i++)
	{
		if (files[i] != QString("dict.db") && files[i] != QString("WordGroup.db"))
		{
			QString dict = files[i];
			int validPos = dict.lastIndexOf(".db");
			dict = dict.left(validPos);
			//cout<<"DictManager::loadDicts->dict["<<i<<"]="<<dict.toUtf8().data()<<endl;
			mDictDBs.push_back(dict);
			QString filePath = dir.absolutePath() + "/";
			DB.openDB(filePath, dict);
		}
	}

	QString command;
	for (int i=0; i<mDictDBs.size(); i++)
	{
		//cout<<"DictManager::loadDicts-->load "<<mDictDBs[i].toUtf8().data()<<endl;
		command = QString("select full_name,description,dict_type from dict_info");
		DB.execQuery(command, QueryT_Read, mDictDBs[i]);
		QString dictName = DB.getTableValue(0, "full_name");
		QString description = DB.getTableValue(0, "description");
		QString dictType = DB.getTableValue(0, "dict_type");
		mDicts.push_back(DictInfo(dictName, dictType, description));
		mDictMap[dictName] = mDictDBs[i];

		command = QString("PRAGMA temp_store = MEMORY;");
		DB.execQuery(command, QueryT_Write, mDictDBs[i]);
	}
}

void DictManager::setQueryResult(QString dictName, QString key, bool exactly)
{
	QString dictFile = mDictMap[dictName];
	mQueryResult.clear();
	QString command;
	command = QString("Select dict_type,full_name from dict_info;");
	DB.execQuery(command, QueryT_Read, dictFile);
	QString dict_type = DB.getTableValue(0,"dict_type");
	QString full_name = DB.getTableValue(0,"full_name");

	//command = QString("Select key,article from articles where key like '%1%';").arg(key);
	command = QString("Select key,article from articles where key >= '%1' and ").arg(key); //a faster query command comparing with 'like' syntax
	QChar last = key[key.size()-1];
	char last_ascii=last.toAscii();
	last_ascii++;
	key.replace(key.size()-1,1,last_ascii);
	command.append(QString("key < '%1';").arg(key));
	DB.execQuery(command, QueryT_Read, dictFile);
	//cout<<"DictManager::setQueryResult-->command="<<command.toUtf8().data()<<endl;
	for (int i=0; i<DB.getRowCount(); i++)
	{
		QString key_i = DB.getTableValue(i,"key");
		if (exactly)
		{
			if (key_i.size() > key.size())
			{
				if (key_i[key.size()] != ' ' && key_i[key.size()] != '(')
					continue;  //do not display
				else if (mIgnorePhraseDicts.contains(dictName) && key_i.size() > key.size()+1 && key_i[key.size()] == ' ')
				{
					QString extra = key_i.right(key_i.size() - key.size());
					extra = extra.simplified();
					if (!extra.isEmpty() && QString(extra[0]).toInt() == 0)
						continue;
					/*if (key_i.size() > key.size()+1)
						if (QString(key_i[key.size()+1]).toInt() == 0)
						{
							cout<<"DictManager::setQueryResult-->QString(key_i[key.size()+1])="<<QString(key_i[key.size()+1]).toUtf8().data()<<endl;
							continue;
						}*/
				}
			}
		}

		QString result_i = DB.getTableValue(i,"article");
		if (dict_type == "xdxf")
			result_i = convertXdxf2Html(result_i);

		mQueryResult.push_back(QueryResult(dict_type, full_name, key_i, result_i));
	};
}

QString DictManager::convertXdxf2Html(QString article)
{
	article.replace(QString("<!--BR-->"), QString("<BR>"));
	article.replace("<c>", "<FONT>");
	article.replace("<c c=", "<FONT COLOR=");
	article.replace("</c>", "</FONT>");

	article.replace("<k>", QString("<FONT COLOR='%1' SIZE=4><B>").arg(xdxf_color_key));
	article.replace("</k>", "</B></FONT>");

	article.replace("<co>", QString("<FONT COLOR='%1'> ").arg(xdxf_color_co));
	article.replace("</co>", "</FONT>");

	article.replace("<ex>", QString("<FONT COLOR='%1'>").arg(xdxf_color_ex));
	article.replace("</ex>", "</FONT>");

	article.replace("<kref>", QString("<FONT COLOR='%1'><U> ").arg(xdxf_color_kref));
	article.replace("</kref>", "</U></FONT>");

	article.replace("<dtrn>", QString("<FONT COLOR='%1'>").arg(xdxf_color_dtrn));
	article.replace("</dtrn>", "</FONT>");

	article.replace("<tense>", QString("<FONT COLOR='%1'><U>").arg(xdxf_color_tense));
	article.replace("</tense>", "</U></FONT>");

	return article;
}

QString DictManager::quickLookup(QString key)
{
	cout<<"DictManager::quickLookup-->key="<<key.toUtf8().data()<<endl;
	QString result;
	for (int i=0; i<mQueryDicts.size(); i++)
	{
		QString dict = mQueryDicts[i];
		setQueryResult(dict, key, true);

		for (int i=0; i<mQueryResult.size(); i++)
			result.append(mQueryResult[i].getFinalArticle() + QString("<br>"));
	}
	return result;
}

QStringList DictManager::quickLookupThesaurus(QString key, QString dict)
{
	//QString key = word->getEnglish();
	//QString commond = "select thesaurus from thesaurus where ";
	QString command = QString("Select key,thesaurus from thesaurus where key >= '%1' and ").arg(key); //a faster query command comparing with 'like' syntax
	QChar last = key[key.size()-1];
	char last_ascii=last.toAscii();
	last_ascii++;
	key.replace(key.size()-1,1,last_ascii);
	command.append(QString("key < '%1';").arg(key));
	//QString dict = mQueryDicts[i];
	QString db = mDictMap[dict];
	DB.execQuery(command, QueryT_Read, db);
	QStringList result;
	for (int i=0; i<DB.getRowCount(); i++)
		result<<DB.getTableValue(i, "key")<<DB.getTableValue(i, "thesaurus");
	//if (DB.getRowCount() >0 )
	return result;
}

void DictManager::lookup(Word* word)
{
	//cout<<"DictManager::lookup"<<endl;
	QString key = word->getEnglish();
	//cout<<"DictManager::lookup->word: "<<key.toUtf8().data()<<endl;
	map<QString, map<QString, QString> >::iterator dict_it;
	for (int i=0; i<mQueryDicts.size(); i++)
	{
		dict_it = word->getExplanations().find(mQueryDicts[i]);
		if (dict_it == word->getExplanations().end()) //need to lookup for explanations
		{
			QString dict = mQueryDicts[i];
			setQueryResult(dict, key, true);
			if (mQueryResult.empty())
			{
				cout	<<"DictManager::lookup-->lookup dictionary "<<dict.toUtf8().data()<<" for word "
						<<key.toUtf8().data()<<" and return empty result."<<endl;
				continue;
			}
			else //set Word::mExplanations
			{
				map<QString, map<QString, QString> >& explanations = word->getExplanations();
				for (int i=0; i<mQueryResult.size(); i++)
				{
					map<QString, QString>& articles = explanations[mQueryResult[i].mDictName];
					articles.insert(make_pair(mQueryResult[i].mKey, mQueryResult[i].getFinalArticle()));
				}
			}
		}
	}
}

QStringList DictManager::getDictList()
{
	QStringList list;
	for (int i=0; i<mDicts.size(); i++)
	{
		list<<mDicts[i].mDictName;
	}

	return list;
}

QStringList DictManager::getQueryDictList()
{
	QStringList list;
	for (int i=0; i<mQueryDicts.size(); i++)
		list<<mQueryDicts[i];

	return list;
}

QStringList DictManager::getIgnorePhraseDictList()
{
	QStringList list;
	for (int i=0; i<mIgnorePhraseDicts.size(); i++)
		list<<mIgnorePhraseDicts[i];

	return list;
}

void DictManager::setQueryDictList(vector<QString>& list)
{
	mQueryDicts.clear();
	for (int i=0; i<list.size(); i++)
		mQueryDicts.push_back(list[i]);
}

void DictManager::setIgnorePhraseDictsList(vector<QString>& list)
{
	mIgnorePhraseDicts.clear();
	for (int i=0; i<list.size(); i++)
		mIgnorePhraseDicts.push_back(list[i]);
}
